package com.qf.system.config;

import com.qf.system.entity.Member;
import com.qf.system.mapper.MemberMapper;
import com.qf.system.mapper.RolePermissionMapper;
import com.qf.system.vo.RoleVo;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 认证       AuthenticatingRealm 抽象
 * 授权  权限  AuthorizingRealm
 */

public class UserRealm extends AuthorizingRealm {
    @Resource
    MemberMapper memberMapper;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException{
        // 获取客户端传递过来的用户名
        String username = (String) authenticationToken.getPrincipal();
        Member member = memberMapper.findByUsername(username);
        if (member == null){
            throw new UnknownAccountException();
        }
        if (member.getStatus() == 0){
            throw new LockedAccountException();
        }
        /**
         * Object principal, 从数据库中获取的用户对象
         * Object hashedCredentials, 用户的密码
         * ByteSource credentialsSalt, 加密盐  因为加密算法是公开
         * String realmName 从前端传递登录用户名
         */
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(member, member.getPassword(), null, username);
        return simpleAuthenticationInfo;
    }

    @Resource
    RolePermissionMapper rolePermissionMapper;

    /**
     * 权限操作
     * 基于权限访问
     * 基于角色访问
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 1 获取登录用户信息
        Member member = (Member) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 2 通过用户ID获取所有的角色权限信息
        Long memberId = member.getId();
        List<RoleVo> roleVos = rolePermissionMapper.selectRolesById(memberId);

        //3 转化数据 设置到simpleAuthorizationInfo中
        Set<String> roles = new HashSet<>();
        Set<String> permissions = new HashSet<>();

        roleVos.forEach(roleVo -> {
            roles.add(roleVo.getName());
            roleVo.getPermissions().forEach(permission -> {
                permissions.add(permission.getName());
            });
        });

        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }
}
